package com.woniuxy.shiro_config;
import com.woniuxy.filtes.JWTFilter;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName ShiroConfig
 * @Description TODO
 * @Author LI.hh
 * @Date 2022/9/6 20:17
 * @Version 1.0
 */
@Configuration
public class ShiroConfig {
    /**
     * 类似之前的ini配置文件shiro-realm.ini的配置，配置默认的安全管理器，并注入我们的自定义域
     * @param myJWTRealm
     * @return
     */
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(MyJWTRealm myJWTRealm){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager(myJWTRealm);
        defaultWebSecurityManager.setRealm(myJWTRealm);
        return defaultWebSecurityManager;
    }
    /**
     * shiro的过滤器配置，注入上面创建的SecurityManager
     * @param securityManager
     * @return
     */
    @Bean("shiroFilterFactoryBean")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //1.注入 安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //2.配置我们的过滤器，只是注册而已，还未生效，因为，我们要 拦截某个url吧
        Map<String, Filter> filters = new HashMap<>();
        filters.put("jwt",new JWTFilter());
        shiroFilterFactoryBean.setFilters(filters);
        //3.开始配置 url 映射上面的key：  jwt
        Map<String, String> filterChainDefinitionMap = new HashMap<>();
        //3.2 登录请求要放行,anon表示匿名访问
        //3.1 jwt这个key的过滤器，拦截所有请求
        filterChainDefinitionMap.put("/**","jwt");
        filterChainDefinitionMap.put("/login","anon");
        filterChainDefinitionMap.put("/401","anon");
        //我们还需要配置一个 拦截某些url的方案，配置过滤器链
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }
    //开启shiro注解支持
    @Bean
    public AuthorizationAttributeSourceAdvisor
    authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new
                AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }
    /**
     开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
     配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }
    /**
     * Description : 管理Subject主体对象,生命周期的组件,用户只是打印下生产销毁日志什么的,请参考spring中bean的生命周期 <b
     * @return org.apache.shiro.spring.LifecycleBeanPostProcessor
     **/
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

}
